package com.smart.system.service;

import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.smart.business.dao.LocalDictDao;
import com.smart.common.utils.*;
import com.smart.entity.business.CompanyEntity;
import com.smart.entity.business.MeterTypeEntity;
import com.smart.entity.system.DeptEntity;
import com.smart.entity.system.DictEntity;
import com.smart.model.exception.SmartException;
import com.smart.mybatis.service.impl.BaseServiceImpl;
import com.smart.service.business.CompanyService;
import com.smart.service.business.DynamicTableService;
import com.smart.service.system.DeptService;
import com.smart.service.system.DictService;
import com.smart.system.dao.DictDao;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.security.mscapi.CPublicKey;

import java.util.*;
import java.util.stream.Collectors;

import static com.smart.common.constant.SmartConstant.INT_ZERO;
import static com.smart.common.constant.SmartConstant.IS_NEW;

/**
 * 字典 ServiceImpl
 *
 * @author wf
 * @since 2022-01-17 07:42:32
 */
@Service("dictService")
@Transactional(rollbackFor = Exception.class)
public class DictServiceImpl extends BaseServiceImpl<DictDao, DictEntity> implements DictService {
    @Autowired
    private CompanyService  companyService;
    @Autowired
    private DeptService deptService;
    @Autowired
    private LocalDictDao dictDao;
    @Autowired
    private DynamicTableService dynamicTableService;
    /**
     * 新增
     *
     * @param entity bean实体
     * @return bean
     */
    @Override
    public DictEntity saveDb(DictEntity entity) {
        DictEntity parent = null;
        if (StringUtil.isBlank(entity.getDictCode())) {
            // 解析祖先链
            String[] ancestors = entity.getAncestors().split(",");
            int level = ancestors.length;


            if (level == 1) {
                // 顶级字典需要手动设置 dictCode
                if (StringUtil.isBlank(entity.getDictCode())) {
                    throw new RuntimeException("顶级字典必须手动设置 dictCode");
                }
            } else if (level <= 3) {
                // 子级和孙级字典，自动生成编码
                parent = super.getById(ancestors[level - 1]);
                if (parent != null && StringUtil.isNotBlank(parent.getDictCode())) {
                    // 获取父级下已有的子节点数量
                    List<DictEntity> siblings = super.lambdaQuery().eq(DictEntity::getParentId, parent.getId()).list();
                    int index = siblings.size() + 1;
                    entity.setDictCode(parent.getDictCode() + "_" + index);
                }
            } else {
                // 超过第三层级，字典编码设为 null
                entity.setDictCode(null);
            }
        }

        boolean b = save(entity);
        // 新增成功后 若是父级字典则修改缓存
        if (b) {
            if (parent != null) {
                CacheUtil.evict("dict", parent.getDictCode());
                CacheUtil.put("dict", parent.getDictCode(), getDictByParentId(parent.getId()));
            }
        }
        // 新增后判断是否需要同步到 表
        syncToCompanyIfNecessary(entity);
        // TODO 新增后判断dict_code格式是否为sys_energy_type_1的格式 同步更新至meter_type表
        syncToMeterTypeIfNecessary(entity);

        return entity;

    }
    private void syncToMeterTypeIfNecessary(DictEntity entity) {
        // 检查字典编码是否符合 sys_energy_type_1 格式
        String dictCode = entity.getDictCode();
        if (dictCode == null) {
            return;
        }
        boolean isMatch = dictCode.matches("^sys_energy_type_\\d+$");
        if (!isMatch) {

            return;
        }
        // 符合条件 插入meter_type表
        MeterTypeEntity meterType = getMeterTypeEntity(entity);
        Db.save(meterType);
    }
    private void syncToCompanyIfNecessary(DictEntity entity) {
        // 检查字典编码是否符合 sys_company_1 或 sys_company_1_1 格式
        String dictCode = entity.getDictCode();
        if (dictCode == null) {
            return;
        }
        boolean isMatch;
        // 允许：sys_company_1 或 sys_company_1_2
        isMatch = dictCode.matches("^sys_company_\\d+(?:_\\d+)?$");
        if (!isMatch) {
            return;
        }


        // 符合条件，插入 sys_company 表和sys_dept
        CompanyEntity company = getCompanyEntity(entity);
        DeptEntity dept = getDeptEntity(entity);
        // 插入公司表,插入部门表,插入关系表
        Db.save(company);
        Db.save(dept);

        // === 新增：动态建表逻辑 ===
        //确保只能是sys_company_1_2的格式
        if (!dictCode.matches("^sys_company_\\d+_\\d+$")) {
            return;
        }
        String tableName = entity.getDictCode(); // 表名为字典的 dictCode（如 sys_company_1_2）
        boolean tableCreated = dynamicTableService.createTable(tableName);
        if (!tableCreated) {
            throw new RuntimeException("动态表创建失败：" + tableName);
        }
        // === 新增结束 ===

    }

    @NotNull
    private static MeterTypeEntity getMeterTypeEntity(DictEntity entity) {
        MeterTypeEntity meterType = new MeterTypeEntity();
        meterType.setName(entity.getDictName());
        meterType.setId(entity.getId());
        meterType.setCreateDate(entity.getCreateDate());
        return meterType;
    }
    @NotNull
    private static CompanyEntity getCompanyEntity(DictEntity entity) {
        CompanyEntity company = new CompanyEntity();
        company.setCompanyName(entity.getDictName());
        company.setDictId(entity.getId());
        company.setSocialCode(entity.getDictValue());
        company.setIsDeleted("0");
        company.setCreateBy(entity.getCreateBy());
        company.setCreateUser(entity.getCreateUser());
        company.setCreateDept(entity.getCreateDept());
        company.setCreateOrganization(entity.getCreateOrganization());
        company.setCreateDate(entity.getCreateDate());
        company.setUpdateBy(entity.getUpdateBy());
        company.setUpdateDate(entity.getUpdateDate());
        company.setRemarks(entity.getRemarks());

        // 经纬度等字段默认值（根据需求可调整）
        company.setLongitude("0");
        company.setLatitude("0");
        company.setRegion("默认区域");
        return company;
    }
    private static DeptEntity getDeptEntity(DictEntity entity) {
        DeptEntity dept = new DeptEntity();
        boolean isYunYing = entity.getDictCode().matches("^sys_company_\\d+$");
        dept.setDeptType(isYunYing?"1":"2");
        dept.setDeptCode(entity.getDictValue());
        dept.setDeptName(entity.getDictName());
        dept.setIsDeleted("0");
        dept.setCreateDate(entity.getCreateDate());
        dept.setCreateUser(entity.getCreateUser());
        dept.setCreateUserName(entity.getCreateUserName());
        dept.setCreateUserAccount(entity.getCreateUserAccount());
        dept.setCreateDept(entity.getCreateDept());
        dept.setCreateDeptName(entity.getCreateDeptName());
        dept.setCreateOrganization(entity.getCreateOrganization());
        dept.setCreateOrganizationName(entity.getCreateOrganizationName());
        dept.setUpdateDate(entity.getUpdateDate());
        dept.setUpdateBy(entity.getUpdateBy());
        dept.setUpdateDate(entity.getUpdateDate());
        dept.setRemarks(entity.getRemarks());
        dept.setSort(entity.getSort());
        dept.setStatus("1");
        dept.setId(entity.getId());
        dept.setAncestors(entity.getAncestors());
        dept.setParentId(entity.getParentId());
        return dept;
    }


    @Override
    public DictEntity updateDb(DictEntity entity) {
        // 先获取字典的code
        DictEntity parent;
        boolean isParent = false;
        if (StringUtil.isBlank(entity.getDictCode())) {
            // 若是子集则获取顶级父级
            String[] ancestors = entity.getAncestors().split(",");
            if (ancestors.length > 1) {
                parent = super.getById(ancestors[1]);
            } else {
                throw new SmartException("获取所属字典失败！");
            }
        } else {
            parent = super.getById(entity.getId());
            isParent = true;
        }
        String code = parent.getDictCode();
        boolean b = updateById(entity);
        // 修改成功后 若是父级字典则修改缓存
        if (b) {
            CacheUtil.evict("dict", code);
            if (isParent) {
                code = entity.getDictCode();
            }
            List<DictEntity> values = getDictByParentId(parent.getId());
            if (values.isEmpty()) {
                CacheUtil.put("dict", code, values);
            }
        }
        // 检查字典编码是否符合 sys_company_1 或 sys_company_1_1 格式
        String dictCode = entity.getDictCode();
        if (dictCode == null) {
            return entity;
        }
        boolean isMatch;
        // 允许：sys_company_1 或 sys_company_1_2
        isMatch = dictCode.matches("^sys_company_\\d+(?:_\\d+)?$");
        if (!isMatch) {
            return entity;
        }
        //从数据库中查询到公司信息
        CompanyEntity company = companyService.getByValues(entity.getOldDictValue());
        if (company == null) {
            throw new IllegalArgumentException("公司信息不存在");
        }
        DeptEntity  dept = deptService.getDeptByValues(entity.getOldDictValue());
        if (dept == null) {
            throw new IllegalArgumentException("部门信息不存在");
        }
        DeptEntity deptEntity = getDeptEntity(entity);
        CompanyEntity companyEntity = getCompanyEntity(entity);
        deptEntity.setId(dept.getId());
        companyEntity.setId(company.getId());
        // 更新数据库信息
        Db.updateById(companyEntity);
        Db.updateById(deptEntity);
        return entity;
    }

    /**
     * 保存之前处理
     *
     * @param entity bean 实体
     * @param isAdd  是否新增
     */
    @Override
    public void beforeSaveOrUpdate(DictEntity entity, boolean isAdd) {
        if (!isAdd) {
            if (StringUtil.notBlankAndEquals(entity.getParentId(), entity.getId())) {
                throw new SmartException("父级和本级不能为同一条数据！");
            }
        }
        if (StringUtil.isNotBlank(entity.getDictCode())) {
            DictEntity dictEntity = Db.lambdaQuery(DictEntity.class).eq(DictEntity::getDictCode, entity.getDictCode()).one();
            if (dictEntity != null) {
                if (isAdd) {
                    // 新增
                    throw new SmartException("字典编码已存在！");
                } else {
                    // 编辑
                    if (!entity.getId().equals(dictEntity.getId())) {
                        throw new SmartException("字典编码已存在！");
                    }
                }
            }
        }
        if (StringUtil.notBlankAndContains(entity.getId(), IS_NEW)) {
            entity.setId(null);
        }
        if (StringUtil.isBlank(entity.getParentId()) || StringUtil.notBlankAndEquals(entity.getParentId(), INT_ZERO)) {
            entity.setParentId(INT_ZERO);
            entity.setAncestors(INT_ZERO);
        } else {
            DictEntity dictEntity = super.getById(entity.getParentId());
            if (dictEntity == null) {
                throw new SmartException("父级字典为空！");
            }
            entity.setAncestors(dictEntity.getAncestors() + "," + dictEntity.getId());
        }
    }

    /**
     * 删除
     *
     * @param entity bean实体
     * @return boolean
     */
    @Override
    public boolean delete(DictEntity entity) {
        DictEntity dictEntity = Db.lambdaQuery(DictEntity.class).in(DictEntity::getId,entity.getId()).one();
        List<String> codes = new ArrayList<>();
        if (StringUtil.isBlank(dictEntity.getDictCode())) {
            // 若是子集则获取顶级父级
            String[] ancestors = dictEntity.getAncestors().split(",");
            if (ancestors.length > 1) {
                DictEntity parent = super.getById(ancestors[1]);
                if (parent != null) {
                    codes.add(parent.getDictCode());
                }
            }
        } else {
            codes.add(dictEntity.getDictCode());
        }

        boolean b = Db.removeById(dictEntity);
        if (b) {
            //删除子集
            //查询子集实体,循环调用删除方法
            List<DictEntity> children = entity.getChildren();
            if (children != null && !children.isEmpty()) {
                for (DictEntity child : children) {
                    delete(child);
                }
            }
            Db.remove(Db.lambdaQuery(DictEntity.class).like(DictEntity::getAncestors,entity.getId()).getWrapper());
            // 清除缓存
            CacheUtil.evictKeys("dict", codes);
        }
        // 检查字典编码是否符合 sys_company_1 或 sys_company_1_1 格式
        String dictCode = entity.getDictCode();
        if (dictCode == null) {
            return b;
        }
        boolean isMatch;
        // 允许：sys_company_1 或 sys_company_1_2
        isMatch = dictCode.matches("^sys_company_\\d+(?:_\\d+)?$");
        if (!isMatch) {
            return b;
        }
        //从数据库中查询到公司信息
        CompanyEntity company = companyService.getByValues(entity.getDictValue());
        if (company == null) {
            throw new IllegalArgumentException("公司信息不存在");
        }
        DeptEntity  dept = deptService.getDeptByValues(entity.getDictValue());
        if (dept == null) {
            throw new IllegalArgumentException("部门信息不存在");
        }
        CompanyEntity companyEntity = getCompanyEntity(entity);
        DeptEntity  deptEntity = getDeptEntity(entity);
        companyEntity.setId(company.getId());
        deptEntity.setId(dept.getId());
        Db.removeById(companyEntity);
        Db.removeById(deptEntity);
        return b;
    }

    @Override
    public List<DictEntity> getDictByCode(String code) {
        List<DictEntity> dictList = CacheUtil.get("dict", code, List.class);
        if (ListUtil.isEmpty(dictList)) {
            List<DictEntity> list = Db.lambdaQuery(DictEntity.class).eq(DictEntity::getDictCode, code).orderByAsc(DictEntity::getSort).list();
            if (ListUtil.isNotEmpty(list)) {
                dictList = getDictByParentId(list.get(0).getId());
                CacheUtil.put("dict", code, dictList);
            }
        }
        return dictList;
    }

    @Override
    public Map<String, List<DictEntity>> getDictByCodes(String codes) {
        Map<String, List<DictEntity>> map = MapUtil.newHashMap();
        if (StringUtil.isNotBlank(codes)) {
            List<String> codeList = ListUtil.newArrayList(codes.split(","));
            // 去重
            Set<String> codeSet = SetUtil.newHashSet(codeList);
            for (String code : codeSet) {
                map.put(code, getDictByCode(code));
            }
            return map;
        }
        return null;
    }

    /**
     * 通过父级 获取字典
     *
     * @param parentId 父级ID
     * @return list
     */
    @Override
    public List<DictEntity> getDictByParentId(String parentId) {
        List<DictEntity> list = Db.lambdaQuery(DictEntity.class).like(DictEntity::getAncestors, parentId).orderByAsc(DictEntity::getSort).list();
        DictEntity parent = super.getById(parentId);
        if (parent == null) {
            throw new SmartException("获取字典为空！");
        }
        DictEntity dictEntity = formatDict(parent, list);
        return dictEntity.getChildren();
    }

    /**
     * 递归处理字典
     *
     * @param dictEntity 要处理的字典bean
     * @param dictList   所有的字典List
     * @return DictEntity
     */
    public DictEntity formatDict(DictEntity dictEntity, List<DictEntity> dictList) {
        List<DictEntity> list = new ArrayList<>();
        for (DictEntity dict : dictList) {
            if (String.valueOf(dict.getParentId()).equals(dictEntity.getId())) {
                list.add(dict);
            }
        }
        List<DictEntity> children = new ArrayList<>();
        List<DictEntity> collect = list.stream().sorted(Comparator.comparing(DictEntity::getSort)).collect(Collectors.toList());
        for (DictEntity dict : collect) {
            dict = formatDict(dict, dictList);
            children.add(dict);
        }
        dictEntity.setChildren(children);
        return dictEntity;
    }


    /**
     * 获取字典树
     *
     * @param entity bean对象
     * @return list
     */
    @Override
    public List<DictEntity> getTree(DictEntity entity) {
        return TreeUtil.buildTree(super.findList(entity));
    }

    /**
     * 获取字典名称
     *
     * @param dictCode     字典code
     * @param dictValue    字典值
     * @param defaultValue 默认值
     * @return String
     * todo 只支持一级字典
     */
    @Override
    public String getDictName(@NotNull String dictCode, @NotNull String dictValue, String defaultValue) {
        List<DictEntity> list = getDictByCode(dictCode);
        List<String> result = new ArrayList<>();
        if (ListUtil.isNotEmpty(list)) {
            List<DictEntity> format = TreeUtil.toList(list);
            String[] values = dictValue.split(",");
            for (String value : values) {
                format.stream().filter(item -> StringUtil.notBlankAndEquals(value, item.getDictValue())).findFirst().ifPresent(first -> {
                    result.add(first.getDictName());
                });
            }
        }
        return result.isEmpty() ? defaultValue : StringUtil.join(result, ",");
    }

    /**
     * 获取字典值
     *
     * @param dictCode     字典code
     * @param dictName     字典名称
     * @param defaultValue 默认值
     * @return String
     * todo 只支持一级字典
     */
    @Override
    public String getDictValue(@NotNull String dictCode, @NotNull String dictName, String defaultValue) {
        List<DictEntity> list = getDictByCode(dictCode);
        if (ListUtil.isNotEmpty(list)) {
            for (DictEntity dict : list) {
                if (StringUtil.notBlankAndEquals(dict.getDictName(), dictName)) {
                    return dict.getDictValue();
                }
            }
        }
        return defaultValue;
    }

    /**
     * 获取字典数据集
     *
     * @param id 主键ID
     * @return List
     */
    @Override
    public List<DictEntity> getValues(String id) {
        List<DictEntity> list = Db.lambdaQuery(DictEntity.class).like(DictEntity::getAncestors, id).orderByAsc(DictEntity::getSort).list();
        list.forEach(x -> {
            x.setOldDictName(x.getDictName());
            x.setOldDictValue(x.getDictValue());
            x.setOldSort(x.getSort());
        });
        return TreeUtil.buildTree(list);
    }
}